package com.gj.modules.gj.controller;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import com.fasterxml.jackson.core.TreeNode;
import com.gj.common.annmapper.MybatisBaseDaoCRUD;
import com.gj.common.annotation.TxbyLogger;
import com.gj.common.data.CommonApiModelMapExt;
import com.gj.common.data.CommonMybaitsDataMapExt;
import com.gj.common.utils.IPUtils;
import com.gj.common.utils.util.ChkUtil;
import com.gj.common.utils.util.HttpToolUtil;
import com.gj.common.utils.util.MD5Util;
import com.gj.common.utils.util.SpringEhcacheUtil;
import com.gj.common.utils.util.Times;
import com.gj.modules.gj.entity.SysApiUser;
import com.google.common.collect.Maps;

public class CommonController  {
	@Autowired
	public MybatisBaseDaoCRUD mBaseDao;
	@Autowired
	public SpringEhcacheUtil springEhcacheUtil;
	public String apiTokenCachName = "apiTokenCache";// 缓存名称
	private HttpServletRequest request;
	private HttpServletResponse response;

	public boolean isHisErr;// 是否his接口异常
	public String  fullClassNamePre="his-";// his Api配置typeFlag 前缀
	public boolean isTokenValid;// 是否token有效
	public static String apiUserId = "";// 用户id
	public String userToken = "";// 当前token
	public Integer reParamType ;// 当前请求类型// 0:web,1:android,2:iphone

	public String clientIP = "";// 当前IP
	public String requestMethod = "";// 当前请求方法
	public  String tempTableName = "";// in查询时超过1000创建的临时表名
	public  boolean isGlobaltempTable=true;//是全局（所有会话）还是本地（当前会话）
	
	public String userAgent="";//用户代理头
	public String errmsg="";//提示信息
	public Integer  errcode=0;//0为正常，其他失败
	public String info;//开发内部提示信息
	public String msg;//提示信息
	public Integer  code;//1为正常，其他失败
	public Integer  expires;//有效期秒
	public String cacheTreeData="cacheTreeData";//
	private static Logger logger = LoggerFactory.getLogger(CommonController.class);
	public String demoDeviceSN="af24b555b64b1e6c";//默认demo 设备数据绑定
	
	
	
	 

	/**
	 * 上传单文件（文件name参数名file）,按日期hh:mmss:sss命名 code 4017: 上传出现异常 4018:
	 * 上传文件大小受限制（不能超过2M） 4019:文件格式受限制（支持gif、png、jpg、bmp）
	 * 
	 * @param request
	 * @param savePath
	 * @return
	 */
	 
	public Map fileUpload(HttpServletRequest request, String savePath) {
		Map m = new HashMap();
		m.put(CommonApiModelMapExt.ERRCODE, 4017);
		m.put(CommonApiModelMapExt.CODE, 4017);
		m.put(CommonApiModelMapExt.ERRMSG, "上传出现异常");
		m.put(CommonApiModelMapExt.MSG, "上传出现异常");
		m.put(CommonApiModelMapExt.INFO, "上传出现异常");
		m.put("url", "");
		try {
			Date date = new Date();
			String newName = Times.getDateToStringHHmmssSSS(date);// 自定义文件名字
			MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
			CommonsMultipartFile orginalFile = (CommonsMultipartFile) multipartRequest
					.getFile("tradingCertificatePicFile");// 表单中对应的文件名；
			if (orginalFile != null && !orginalFile.isEmpty()) {
				String fileName = orginalFile.getOriginalFilename();
				String suffix = fileName.substring(fileName.indexOf("."));// 获得后缀名

				long size = orginalFile.getSize();
				/*
				 * if(orginalFile.getSize()>6024*2000){ m.put("code", "4018");
				 * m.put("info","图片上传文件大小受限制（不能超过2M）"); m.put("msg",
				 * "图片不能大于2M"); return m; }
				 */

				if (!suffix.equals(".bmp") && !suffix.equals(".gif") && !suffix.equals(".png")
						&& !suffix.equals(".jpg")) {
					m.put("code", "4019");
					m.put("info", "文件格式受限制（支持gif、png、jpg、bmp）");
					m.put("msg", "上传格式应为gif、png、jpg、bmp");
					m.put(CommonApiModelMapExt.ERRCODE, 4019);
					m.put(CommonApiModelMapExt.CODE, 4019);
					m.put(CommonApiModelMapExt.ERRMSG,"文件格式受限制（支持gif、png、jpg、bmp）");
					m.put(CommonApiModelMapExt.MSG,"文件格式受限制（支持gif、png、jpg、bmp）");
					m.put(CommonApiModelMapExt.INFO, "文件格式受限制（支持gif、png、jpg、bmp）");
					return m;
				}
				fileName = newName + suffix;
				File file = new File(savePath);
				if (!file.exists()) {// 判断文件夹是否存在，不存在就根据上面的路径创建文件夹
					file.mkdirs();
				}
				String realpath = request.getSession().getServletContext().getRealPath(savePath);// 给予存储路径
				File f = new File(realpath + File.separator + fileName);
				String url = savePath + fileName;// 获得相对路径
				FileUtils.copyInputStreamToFile(orginalFile.getInputStream(), f);// 获取文件，并按照路径保存
				
				m.put(CommonApiModelMapExt.ERRCODE, 0);
				m.put(CommonApiModelMapExt.CODE, 1);
				m.put(CommonApiModelMapExt.ERRMSG, "上传成功");
				m.put(CommonApiModelMapExt.MSG, "上传成功");
				m.put(CommonApiModelMapExt.INFO, "上传成功");
				m.put("url", url);
				m.put("date", date);
				return m;
			}

		} catch (Exception e) {
			e.printStackTrace();

			return m;
		}

		return m;
	}

	/**
	 * 根据用户获取token
	 * 
	 * @Description: TODO(这里用一句话描述这个方法的作用)
	 * @param userData
	 * @return token,用户id字符+“#”动态码
	 */
	public String getCreateTokenBySysApiUser(SysApiUser userData) {
		String userId = userData.getId() + "_";
		String verifyCode = MD5Util.getMD5ofStr(userId + userData.getPassWord() + new Date().getTime(), 2);
		String token = userId + verifyCode;
		return token;
	}

	/**
	 * 根据用户获取token并放入cache
	 * @param userData
	 * @return
	 */
	public CommonApiModelMapExt getCreateTokenBySysApiUserAndPutCache(SysApiUser userData) {
		String userId = userData.getId();
		String verifyCode = MD5Util.getMD5ofStr(userId + userData.getPassWord() + new Date().getTime(), 2);
		String token = userId + "_" + verifyCode;
		putTokenCache(userId + "_token", token);
		CommonApiModelMapExt m=new CommonApiModelMapExt(0,  "token正常", null, null, null);
		m.put("token", token);
//		long expires=
//				println()println(springEhcacheUtil.getCacheManager().getCache("apiTokenCache"))
//				println()
		long expires=springEhcacheUtil.getCacheManager().getCache("apiTokenCache").getCacheConfiguration().getTimeToIdleSeconds();
		m.put("expires",expires);
		return 	m;
	}
	/**
	 * 根据用户获取token并放入cache
	 * @param userData
	 * @return
	 */
	public CommonApiModelMapExt getDemoCreateTokenBySysApiUserAndPutCache(SysApiUser userData) {
		String demoPrefix="demo:";
		String userId = demoPrefix+userData.getId();
		String verifyCode = MD5Util.getMD5ofStr(userId + userData.getPassWord() + new Date().getTime(), 2);
		String token = userId + "_" + verifyCode;
		putTokenCache(userId + "_token", token);
		CommonApiModelMapExt m=new CommonApiModelMapExt(0,  "token正常", null, null, null);
		m.put("token", token);
//		long expires=
//				println()println(springEhcacheUtil.getCacheManager().getCache("apiTokenCache"))
//				println()
		long expires=springEhcacheUtil.getCacheManager().getCache("apiTokenCache").getCacheConfiguration().getTimeToIdleSeconds();
		m.put("expires",expires);
		return 	m;
	}
	 
	 
	public CommonApiModelMapExt chekTokenCahceValid(String token, Integer type){
/*		if(true){
			isTokenValid = true;
//		apiUserId = data[0];// 用户id
			userToken = token;// 当前token
			reParamType = type;// 当前请求类型（须）0：web,1:app
			this.springEhcacheUtil.put(apiTokenCachName, apiUserId + "_token", token);
			return new CommonApiModelMapExt(0,"token正常", null, null, null) ;
			
		}*/
		List oldTypeList = Arrays.asList(0, 1,2);// 0:web,1:android,2:iphone
		if (!oldTypeList.contains(type)) {
			isTokenValid = false;
			apiUserId = "";// 用户id
			userToken = "";// 当前token
			reParamType = null;// 当前请求类型// 0:web,1:android,2:iphone
//			return writeReturnJson(SERVER_ERR.CODE_1.getCode(), "验证失败,参数不正确", "验证失败,参数不正确");
			return new CommonApiModelMapExt(4000, "type验证失败,参数类型不正确", null, null, null);
		}else {
			try {
				String[] data = token.split("_");
				if (data.length < 2) {
					isTokenValid = false;
					apiUserId = "";// 用户id
					userToken = "";// 当前token
					reParamType = null;// 当前请求类型（须）0：web,1:app
					return new CommonApiModelMapExt(4001, "token验证失败,格式不正确", null, null, null);
				}else{
					apiUserId = data[0];// 用户id
					String oldtoken = (String) springEhcacheUtil.get(apiTokenCachName, apiUserId + "_token");
					if (ChkUtil.isEmpty(oldtoken)) {
						isTokenValid = false;
						apiUserId = "";// 用户id
						userToken = "";// 当前token
						reParamType = null;// 当前请求类型（须）0：web,1:app
						return new CommonApiModelMapExt(4002, "token验证失效,请重新登录验证", null, null, null);
					}
					
					if (!oldtoken.equals(token)) {
						isTokenValid = false;
						apiUserId = "";// 用户id
						userToken = "";// 当前token
						reParamType = null;// 当前请求类型（须）0：web,1:app
						 return new CommonApiModelMapExt(4003,"token验证失效，用户已在其他设备登录,请重新登录验证", null, null, null) ;
					} else{
						isTokenValid = true;
						apiUserId = data[0];// 用户id
						userToken = token;// 当前token
						reParamType = type;// 当前请求类型（须）0：web,1:app
						this.springEhcacheUtil.put(apiTokenCachName, apiUserId + "_token", token);
						return new CommonApiModelMapExt(0,"token正常", null, null, null) ;
					}
				}
			} catch (Exception e) {
				isTokenValid = false;
				apiUserId = "";// 用户id
				userToken = "";// 当前token
				reParamType = null;// 当前请求类型（须）0：web,1:app
				e.printStackTrace();
				saveLog("传入的token异常，可能格式不正确");
				return new CommonApiModelMapExt(5000,"token正常", null, null, null) ;
			}
			
		}

	}

	public Map tokenNotValid(CommonApiModelMapExt map) throws IOException {
		if (!this.isTokenValid) {
			map.clear();
			map =new CommonApiModelMapExt(1,"token异常", null, null, null) ;
		} else {
			map =  new CommonApiModelMapExt(1,"token正常", null, null, null);
		}
		return map;
	}

 

	/**
	 * 存放token缓存，默认token,存活1小时，间隔1小时内有效
	 * 
	 * @param key
	 * @param value
	 */
	/*
	 * public void putTokenCache(String key,String value){
	 * this.springEhcacheUtil.put(apiTokenCachName, key, value); }
	 */
	public void putTokenCache(String key, String value) {
		this.springEhcacheUtil.put(apiTokenCachName, key, value);
	}

	/**
	 * 用户手动日志保存(格式)
	 * 
	 * @param message
	 */
	public void saveLog(String message) {
		if (isTokenValid) {
			TxbyLogger.getLogger(TxbyLogger.class).log(TxbyLogger.getTxbyLoggerLevel(), "触发时间：" + Times.getTimes() + "，IP:" + clientIP + ",请求参数类型" + reParamType + ",请求方法类型"
					+ requestMethod + ",用户：" + apiUserId + "" + "，信息说明：" + message + "");
			/*logger.warn("触发时间：" + Times.getTimes() + "，IP:" + clientIP + ",请求参数类型" + reParamType + ",请求方法类型"
					+ requestMethod + ",用户：" + apiUserId + "" + "，信息说明：" + message + "");*/
		} else {
		/*	logger.warn("触发时间：" + Times.getTimes() + "，IP:" + clientIP + ",请求参数类型" + reParamType + ",请求方法类型"
					+ requestMethod + "，信息说明：" + message + "");*/
			
			TxbyLogger.getLogger(TxbyLogger.class).log(TxbyLogger.getTxbyLoggerLevel(), "触发时间：" + Times.getTimes() + "，IP:" + clientIP + ",请求参数类型" + reParamType + ",请求方法类型"
					+ requestMethod + "，信息说明：" + message + "");
		}
	}

	
	
	/**
	 * @Description:sql in条件查询拆分
	 * @param sqlId
	 * @return
	 */
	public static String getSplitInSql(String[] sqlId) {
		String sql = "";
		for (String str : sqlId) {
			sql += "'" + str + "',";
		}
		if (!ChkUtil.isEmpty(sql)) {
			sql = sql.substring(0, sql.length() - 1);
		}
		return sql;
	}

	/**
	 * @Description: sql in条件查询拆分
	 * @param sqlId
	 * @return
	 */
	public static String getSplitInSql(Set<String> sqlId) {
		String sql = "";
		for (String str : sqlId) {
			sql += "'" + str + "',";
		}
		if (!ChkUtil.isEmpty(sql)) {
			sql = sql.substring(0, sql.length() - 1);
		}
		return sql;
	}

	/**
	 * @Description: 保存数据表中，外键id的“，”分割的拆分
	 * @param sqlId
	 * @return
	 */
	public static String getSplitNewString(String[] sqlId) {
		String sql = "";
		for (String str : sqlId) {
			sql += str + ",";
		}
		if (!ChkUtil.isEmpty(sql)) {
			sql = sql.substring(0, sql.length() - 1);
		}
		return sql;
	}

	/**
	 * @Description: 保存数据表中，外键id的“，”分割的拆分
	 * @param sqlId
	 * @return
	 */
	public static String getSplitNewString(Set<String> sqlId) {
		String sql = "";
		for (String str : sqlId) {
			sql += str + ",";
		}
		if (!ChkUtil.isEmpty(sql)) {
			sql = sql.substring(0, sql.length() - 1);
		}
		return sql;
	}
	 
	
	/**
	 * @Description: TODO(这里用一句话描述这个方法的作用) 
	 * @param tempTableName
	 * @return
	 */
	public  String  getUniqueTempTableName(String tempTableName){
		String pre=isGlobaltempTable?"##temp_":"#temp_";
		String suf=""+new Date().getTime();
		tempTableName=tempTableName==null?pre+suf:pre+tempTableName+suf;
		return tempTableName;
	}
	
	@ModelAttribute
	public void initUserRequest(HttpServletRequest request) throws IOException{
		String userAgent=request.getHeader("user-agent");
		userAgent=userAgent.toUpperCase();
		if(userAgent.contains("ANDROID")){
			this.userAgent="ANDROID";
		}else if(userAgent.contains("IPHONE")){
			this.userAgent="IPHONE";
		}else if(userAgent.contains("CHROME")){
			this.userAgent="CHROME";
		}else if(userAgent.contains("GECKO")){
			this.userAgent="GECKO";
		}
		this.request = request;
		this.response = response;
		this.requestMethod = request.getMethod().toUpperCase();
		try {
			this.clientIP = IPUtils.getIpAddr(request);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	 
	/**
	 * http请求返回json
	 * @param httpUrl
	 * @param httpType
	 * @param maps
	 * @return
	 * @throws IOException
	 */
	public String getHttpResponseContent(String httpUrl,String httpType, Map<String, String> maps) throws IOException{
	    String responseContent=HttpToolUtil.getInstance().sendHttpCustom(httpUrl, httpType, maps, false, null);
		return responseContent;
	}
	 
	 
 
	 
	
	 
	/**
	 * 反转List 集合数据
	* @Title: getDeviceHosInfoByRegionListReveseString 
	* @Description: TODO(这里用一句话描述这个方法的作用) 
	* @param @param fullRegion
	* @param @return    设定文件 
	* @return String    返回类型 
	* @throws
	 */
	public  static String  getDeviceHosInfoByRegionListReveseString(List<String> fullRegion){
		String regionName="";
		int size=fullRegion!=null?fullRegion.size():0;
		for(int i=size-1;i>=0;i--){
			if(i!=0){
				regionName+=fullRegion.get(i)+"-";
			}else{
				regionName+=fullRegion.get(i);
			}
		}
		return regionName;
	}
	

	
	
	
	
}
